unit uDBTreeView;

interface

uses
  SysUtils, Classes, Controls, ComCtrls, DB;

type
  TDBTreeView = class(TTreeView)
  private
    FColunas: TStrings;
    FDataSource: TDataSource;
    procedure SetColunas(const Value: TStrings);
    procedure DblClick; override;

    { Private declarations }
  protected
    { Protected declarations }
  public
    procedure Desenha;
    procedure DesenhaColunas(Coluna: integer; Pai: TTreeNode);
    constructor Create(AOwner: TComponent); override;
  published
    property Colunas: TStrings read FColunas write SetColunas;
    property DataSource: TDataSource read FDataSource write FDataSource;
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('MRSoftware', [TDBTreeView]);
end;

{ TDBTreeView }

constructor TDBTreeView.Create(AOwner: TComponent);
begin
  inherited;
  FColunas := TStringList.Create;
  FColunas.Text := '';
end;

procedure TDBTreeView.DblClick;
var
    Campos, separador: string;
    Busca: Array of Variant;
    I, LevelTemp: Integer;
    Node: TTreeNode;
begin
  inherited;
  Node := Self.Selected;
  LevelTemp := node.Level;
  Campos := ''; separador := '';
  for I := 0 to LevelTemp do
  begin
    Campos := Campos + separador + FColunas[i];
    separador := ';';
  end;

  SetLength(Busca,LevelTemp+1);
  for i := LevelTemp downto 0 do
  begin
    Busca[i] := Node.Text;
    Node := Node.Parent;
  end;

  Self.DataSource.DataSet.Locate(Campos,Busca,[loCaseInsensitive]);
end;

procedure TDBTreeView.Desenha;
var
    Node: TTreeNode;
begin
    Items.Clear;
    FDataSource.DataSet.First;
    while not FDataSource.DataSet.eof do
    begin
        DesenhaColunas(1, nil);
        //FDataSource.DataSet.next;
    end;

end;

procedure TDBTreeView.DesenhaColunas(Coluna : integer; Pai: TTreeNode);
var
    vColunas: integer;
    valorAnterior: String;
    Node: TTreeNode;
begin
    if FDataSource.DataSet.Eof then exit;
    vColunas := FColunas.Count;
    if Coluna > vColunas  then
    begin
        FDataSource.DataSet.next;
        Exit;
    end;

    if Coluna = 1 then
    begin
        Node := Self.Items.Add(nil, FDataSource.DataSet.FieldByName(
            FColunas[Coluna-1]).AsString
        );

    end else
    begin
        Node := Self.Items.AddChild(Pai, FDataSource.DataSet.FieldByName(
           FColunas[Coluna-1]).AsString
        );

    end;

    if Self.Images <> nil then
    begin
        if Self.Images.Count >= (Coluna - 1) then
        begin
            Node.ImageIndex := Coluna - 1;
            Node.SelectedIndex := Coluna - 1;
        end;
    end;

    while (Node.Text = FDataSource.DataSet.FieldByName(FColunas[Coluna-1]).AsString) and
        (not (FDataSource.DataSet.Eof)) do
    begin
        DesenhaColunas(Coluna + 1,  Node);
        //FDataSource.DataSet.next;
    end;

end;

procedure TDBTreeView.SetColunas(const Value: TStrings);
begin
    FColunas.Assign(Value);

end;

end.
